package com.whut.monitor.util;

import com.alibaba.fastjson.JSON;
import com.whut.monitor.dao.IHBaseDao;
import com.whut.monitor.vo.DiagnoseSensorVo;

import java.util.*;
import java.util.concurrent.ForkJoinPool;

import static com.whut.monitor.util.DateUtil.getHbaseDate;
import static com.whut.monitor.util.DateUtil.getTimeS;
import static com.whut.monitor.util.FileUtil.show;

/**
 * 针对武重机床数据、HBase、数据分析等专用的函数，其它机床不通用
 *
 * @author Sandeepin
 *         2017/11/27 0027
 */
public class WuzhongUtil {

    public static String dataNameDS18B20 = "001-SDT00-00,001-SDT00-01,001-SDT00-02,001-SDT00-03,001-SDT00-04,001-SDT00-05,001-SDT00-06,001-SDT00-07,001-SDT01-00,001-SDT01-01,001-SDT01-02,001-SDT01-03,001-SDT01-04,001-SDT01-05,001-SDT01-06,001-SDT01-07,001-SDT02-00,001-SDT02-01,001-SDT02-02,001-SDT02-03,001-SDT02-04,001-SDT02-05,001-SDT02-06,001-SDT02-07,001-SDT03-00,001-SDT03-01,001-SDT03-02,001-SDT03-03,001-SDT03-04,001-SDT03-05,001-SDT03-06,001-SDT03-07,001-SDT04-00,001-SDT04-01,001-SDT04-02,001-SDT04-03,001-SDT04-04,001-SDT04-05,001-SDT04-06,001-SDT04-07,001-SDT05-00,001-SDT05-01,001-SDT05-02,001-SDT05-03,001-SDT05-04,001-SDT05-05,001-SDT05-06,001-SDT05-07,001-SDT06-00,001-SDT06-01,001-SDT06-02,001-SDT06-03";
    public static String dataNameFBG = "001-SFT00-00,001-SFT00-01,001-SFT00-02,001-SFT00-03,001-SFT00-04,001-SFT00-05,001-SFT00-06,001-SFT00-07,001-SFT00-08,001-SFT00-09,001-SFT00-10,001-SFT00-11,001-SFT00-12,001-SFT00-13,001-SFT00-14,001-SFT01-00,001-SFT01-01,001-SFT01-02,001-SFT01-03,001-SFT01-04,001-SFT01-05,001-SFT01-06,001-SFT01-07,001-SFT02-00,001-SFT02-01,001-SFT02-02,001-SFT02-03,001-SFT02-04,001-SFT02-05,001-SFT02-06,001-SFT02-07,001-SFT02-08,001-SFT02-09,001-SFT02-10,001-SFT02-11,001-SFT02-12,001-SFT02-13,001-SFT02-14,001-SFT03-00,001-SFT03-01,001-SFT03-02,001-SFT03-03,001-SFT03-04,001-SFT03-05,001-SFT03-06,001-SFT03-07,001-SFT03-08,001-SFT03-09,001-SFT03-10,001-SFT03-11,001-SFT03-12,001-SFT03-13,001-SFT03-14,001-SFT04-00,001-SFT04-01,001-SFT04-02,001-SFT04-03,001-SFT04-04,001-SFT04-05,001-SFT04-06,001-SFT04-07,001-SFT04-08,001-SFT04-09,001-SFT04-10,001-SFT04-11,001-SFT04-12,001-SFT04-13,001-SFT04-14,001-SFT05-00,001-SFT05-01,001-SFT05-02,001-SFT05-03,001-SFT05-04,001-SFT05-05,001-SFT05-06,001-SFT05-07,001-SFT05-08,001-SFT05-09,001-SFT05-10,001-SFT05-11,001-SFT05-12,001-SFT05-13,001-SFT05-14,001-SFT06-00,001-SFT06-01,001-SFT06-02,001-SFT06-03,001-SFT06-04,001-SFT06-05,001-SFT06-06,001-SFT07-00,001-SFT07-01,001-SFT07-02,001-SFT07-03,001-SFT07-04,001-SFT07-05,001-SFT07-06,001-SFT07-07,001-SFT07-08,001-SFT07-09,001-SFT07-10,001-SFT07-11,001-SFT07-12,001-SFT07-13,001-SFT07-14,001-SFT08-00,001-SFT08-01,001-SFT08-02,001-SFT08-03,001-SFT08-04,001-SFT08-05,001-SFT08-06,001-SFT08-07,001-SFT09-00,001-SFT09-01,001-SFT09-02,001-SFT09-03,001-SFT09-04,001-SFT09-05,001-SFT09-06,001-SFT10-00,001-SFT10-01,001-SFT10-02,001-SFT10-03,001-SFT10-04,001-SFT10-05,001-SFT10-06,001-SFT10-07,001-SFT10-08,001-SFT10-09,001-SFT10-10,001-SFT10-11,001-SFT10-12,001-SFT10-13,001-SFT10-14,001-SFT11-00,001-SFT11-01,001-SFT11-02,001-SFT11-03,001-SFT11-04,001-SFT11-05,001-SFT11-06,001-SFT11-07,001-SFT11-08,001-SFT11-09,001-SFT11-10,001-SFT11-11,001-SFT11-12,001-SFT11-13,001-SFT11-14,001-SFT12-00,001-SFT12-01,001-SFT12-02,001-SFT12-03,001-SFT12-04,001-SFT12-05,001-SFT12-06,001-SFT12-07,001-SFT12-08,001-SFT12-09,001-SFT12-10,001-SFT12-11,001-SFT12-12,001-SFT12-13,001-SFT12-14,001-SFT13-00,001-SFT13-01,001-SFT13-02,001-SFT13-03,001-SFT13-04,001-SFT13-05,001-SFT13-06,001-SFT14-00,001-SFT14-01,001-SFT14-02,001-SFT14-03,001-SFT14-04,001-SFT14-05,001-SFT14-06,001-SFT14-07,001-SFT15-00,001-SFT15-01,001-SFT15-02,001-SFT15-03,001-SFT15-04,001-SFT15-05,001-SFT15-06,001-SFT15-07,001-SFT16-00,001-SFT16-01,001-SFT16-02,001-SFT16-03,001-SFT16-04,001-SFT16-05,001-SFT16-06,001-SFT16-07,001-SFT17-00,001-SFT17-01,001-SFT17-02,001-SFT17-03,001-SFT17-04,001-SFT17-05,001-SFT17-06,001-SFT17-07,001-SFT18-00,001-SFT18-01,001-SFT18-02,001-SFT18-03,001-SFT18-04,001-SFT18-05,001-SFT18-06,001-SFT18-07,001-SFT18-08,001-SFT18-09,001-SFT19-00,001-SFT19-01,001-SFT19-02,001-SFT19-03,001-SFT19-04,001-SFT19-05,001-SFT19-06,001-SFT19-07,001-SFT19-08,001-SFT19-09,001-SFT20-00,001-SFT20-01,001-SFT20-02,001-SFT20-03,001-SFT20-04,001-SFT20-05,001-SFT20-06,001-SFT21-00,001-SFT21-01,001-SFT21-02,001-SFT21-03,001-SFT21-04,001-SFT21-05,001-SFT21-06,001-SFT21-07,001-SFT21-08,001-SFT21-09,001-SFT22-00,001-SFT22-01,001-SFT22-02,001-SFT22-03,001-SFT23-00,001-SFT23-01,001-SFT23-02,001-SFT23-03,001-SFT23-04,001-SFT23-05,001-SFT23-06,001-SFT23-07,001-SFT23-08,001-SFT23-09,001-SFT24-00,001-SFT24-01,001-SFT24-02,001-SFT24-03,001-SFT24-04,001-SFT24-05,001-SFT24-06,001-SFT24-07,001-SFT24-08,001-SFT24-09,001-SFT25-00,001-SFT25-01,001-SFT25-02,001-SFT25-03,001-SFT26-00,001-SFT26-01,001-SFT26-02,001-SFT26-03,001-SFT26-04,001-SFT26-05,001-SFT26-06,001-SFT26-07,001-SFT26-08,001-SFT27-00,001-SFT27-01,001-SFT27-02,001-SFT27-03,001-SFT27-04,001-SFT27-05,001-SFT27-06,001-SFT27-07,001-SFT27-08,001-SFT27-09,001-SFT28-00,001-SFT28-01,001-SFT28-02,001-SFT28-03,001-SFT28-04,001-SFT28-05,001-SFT28-06,001-SFT28-07,001-SFT28-08,001-SFT28-09,001-SFT29-00,001-SFT29-01,001-SFT29-02,001-SFT29-03,001-SFT29-04,001-SFT29-05,001-SFT29-06,001-SFT29-07,001-SFT29-08,001-SFT29-09,001-SFT30-00,001-SFT30-01,001-SFT30-02,001-SFT30-03,001-SFT30-04,001-SFT30-05,001-SFT30-06,001-SFT30-07,001-SFT30-08,001-SFT30-09,001-SFT31-00,001-SFT31-01,001-SFT31-02";
    public static String dataNameFBGS = "001-SST00-00,001-SST00-01,001-SST00-02,001-SST00-03,001-SST00-04,001-SST00-05,001-SST00-06,001-SST00-07,001-SST00-08,001-SST00-09,001-SST00-10,001-SST00-11,001-SST00-12,001-SST00-13,001-SST00-14,001-SST01-00,001-SST01-01,001-SST01-02,001-SST01-03,001-SST01-04,001-SST01-05,001-SST01-06,001-SST01-07,001-SST02-00,001-SST02-01,001-SST02-02,001-SST02-03,001-SST02-04,001-SST02-05,001-SST02-06,001-SST02-07,001-SST02-08,001-SST02-09,001-SST02-10,001-SST02-11,001-SST02-12,001-SST02-13,001-SST02-14,001-SST03-00,001-SST03-01,001-SST03-02,001-SST03-03,001-SST03-04,001-SST03-05,001-SST03-06,001-SST03-07,001-SST03-08,001-SST03-09,001-SST03-10,001-SST03-11,001-SST03-12,001-SST03-13,001-SST03-14,001-SST04-00,001-SST04-01,001-SST04-02,001-SST04-03,001-SST04-04,001-SST04-05,001-SST04-06,001-SST04-07,001-SST04-08,001-SST04-09,001-SST04-10,001-SST04-11,001-SST04-12,001-SST04-13,001-SST04-14,001-SST05-00,001-SST05-01,001-SST05-02,001-SST05-03,001-SST05-04,001-SST05-05,001-SST05-06,001-SST05-07,001-SST05-08,001-SST05-09,001-SST05-10,001-SST05-11,001-SST05-12,001-SST05-13,001-SST05-14,001-SST06-00,001-SST06-01,001-SST06-02,001-SST06-03,001-SST06-04,001-SST06-05,001-SST06-06";
    public static String dataNameFBGT = "001-SFT00-00,001-SFT00-01,001-SFT00-02,001-SFT00-03,001-SFT00-04,001-SFT00-05,001-SFT00-06,001-SFT00-07,001-SFT00-08,001-SFT00-09,001-SFT00-10,001-SFT00-11,001-SFT00-12,001-SFT00-13,001-SFT00-14,001-SFT01-00,001-SFT01-01,001-SFT01-02,001-SFT01-03,001-SFT01-04,001-SFT01-05,001-SFT01-06,001-SFT01-07,001-SFT02-00,001-SFT02-01,001-SFT02-02,001-SFT02-03,001-SFT02-04,001-SFT02-05,001-SFT02-06,001-SFT03-00,001-SFT03-01,001-SFT03-02,001-SFT03-03,001-SFT03-04,001-SFT03-05,001-SFT03-06,001-SFT03-07,001-SFT03-08,001-SFT03-09,001-SFT03-10,001-SFT03-11,001-SFT03-12,001-SFT03-13,001-SFT03-14,001-SFT04-00,001-SFT04-01,001-SFT04-02,001-SFT04-03,001-SFT04-04,001-SFT04-05,001-SFT04-06,001-SFT04-07,001-SFT04-08,001-SFT04-09,001-SFT04-10,001-SFT04-11,001-SFT04-12,001-SFT04-13,001-SFT04-14,001-SFT05-00,001-SFT05-01,001-SFT05-02,001-SFT05-03,001-SFT05-04,001-SFT05-05,001-SFT05-06,001-SFT05-07,001-SFT05-08,001-SFT05-09,001-SFT05-10,001-SFT05-11,001-SFT05-12,001-SFT05-13,001-SFT05-14,001-SFT06-00,001-SFT06-01,001-SFT06-02,001-SFT06-03,001-SFT06-04,001-SFT06-05,001-SFT06-06,001-SFT07-00,001-SFT07-01,001-SFT07-02,001-SFT07-03,001-SFT07-04,001-SFT07-05,001-SFT07-06,001-SFT07-07,001-SFT08-00,001-SFT08-01,001-SFT08-02,001-SFT08-03,001-SFT08-04,001-SFT08-05,001-SFT08-06,001-SFT08-07,001-SFT09-00,001-SFT09-01,001-SFT09-02,001-SFT09-03,001-SFT09-04,001-SFT09-05,001-SFT09-06,001-SFT09-07,001-SFT10-00,001-SFT10-01,001-SFT10-02,001-SFT10-03,001-SFT10-04,001-SFT10-05,001-SFT10-06,001-SFT10-07,001-SFT11-00,001-SFT11-01,001-SFT11-02,001-SFT11-03,001-SFT11-04,001-SFT11-05,001-SFT11-06,001-SFT11-07,001-SFT11-08,001-SFT11-09,001-SFT12-00,001-SFT12-01,001-SFT12-02,001-SFT12-03,001-SFT12-04,001-SFT12-05,001-SFT12-06,001-SFT12-07,001-SFT12-08,001-SFT12-09,001-SFT13-00,001-SFT13-01,001-SFT13-02,001-SFT13-03,001-SFT13-04,001-SFT13-05,001-SFT13-06,001-SFT14-00,001-SFT14-01,001-SFT14-02,001-SFT14-03,001-SFT14-04,001-SFT14-05,001-SFT14-06,001-SFT14-07,001-SFT14-08,001-SFT14-09,001-SFT15-00,001-SFT15-01,001-SFT15-02,001-SFT15-03,001-SFT16-00,001-SFT16-01,001-SFT16-02,001-SFT16-03,001-SFT16-04,001-SFT16-05,001-SFT16-06,001-SFT16-07,001-SFT16-08,001-SFT16-09,001-SFT17-00,001-SFT17-01,001-SFT17-02,001-SFT17-03,001-SFT17-04,001-SFT17-05,001-SFT17-06,001-SFT17-07,001-SFT17-08,001-SFT17-09,001-SFT18-00,001-SFT18-01,001-SFT18-02,001-SFT18-03,001-SFT19-00,001-SFT19-01,001-SFT19-02,001-SFT19-03,001-SFT19-04,001-SFT19-05,001-SFT19-06,001-SFT19-07,001-SFT19-08,001-SFT20-00,001-SFT20-01,001-SFT20-02,001-SFT20-03,001-SFT20-04,001-SFT20-05,001-SFT20-06,001-SFT20-07,001-SFT20-08,001-SFT20-09,001-SFT21-00,001-SFT21-01,001-SFT21-02,001-SFT21-03,001-SFT21-04,001-SFT21-05,001-SFT21-06,001-SFT21-07,001-SFT21-08,001-SFT21-09,001-SFT22-00,001-SFT22-01,001-SFT22-02,001-SFT22-03,001-SFT22-04,001-SFT22-05,001-SFT22-06,001-SFT22-07,001-SFT22-08,001-SFT22-09,001-SFT23-00,001-SFT23-01,001-SFT23-02,001-SFT23-03,001-SFT23-04,001-SFT23-05,001-SFT23-06,001-SFT23-07,001-SFT23-08,001-SFT23-09,001-SFT24-00,001-SFT24-01,001-SFT24-02";
    public static String dataNameENV = "001-SET00-00,001-SET00-01,001-SET01-00,001-SET01-01";
    public static String dataNameCCD = "001-SCD-00,001-SCD-01,001-SCD-02";
    public static String dataNameCNC = "001-CH,001-XPOS,001-YPOS,001-ZPOS,001-MAPOS,001-FR,001-SP,001-XPWR,001-YPWR,001-ZPWR,001-MAPWR,001-XFU,001-YFU,001-ZFU,001-MAFU,001-PA";
    // 真正有数据的FBG下标
    public static int[] dataindexFBGS = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,20,21,22,23,24,25,26,27,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,120,121,122,123,124,125,126};
    public static int[] dataindexFBGT = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,20,21,22,23,24,25,26,27,40,41,42,43,44,45,46,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,120,121,122,123,124,125,126,140,141,142,143,144,145,146,147,160,161,162,163,164,165,166,167,180,181,182,183,184,185,186,187,200,201,202,203,204,205,206,207,220,221,222,223,224,225,226,227,228,229,240,241,242,243,244,245,246,247,248,249,260,261,262,263,264,265,266,280,281,282,283,284,285,286,287,288,289,300,301,302,303,320,321,322,323,324,325,326,327,328,329,340,341,342,343,344,345,346,347,348,349,360,361,362,363,380,381,382,383,384,385,386,387,388,400,401,402,403,404,405,406,407,408,409,420,421,422,423,424,425,426,427,428,429,440,441,442,443,444,445,446,447,448,449,460,461,462,463,464,465,466,467,468,469,480,481,482};

    // 获取Hbase数据库中指定天的 电类温度 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static double[][] getHbaseAllDSB(String date, List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 52;
        // title赋值
        String[] array = dataNameDS18B20.split(",");
        title.addAll(Arrays.asList(array));
        // 取数据
        String sensorType = "DT";
        String table = "wuzhong";
        String start = "01" + sensorType + getHbaseDate(date) + "000000";
        String end   = "01" + sensorType + getHbaseDate(date) + "235959";
        Map<String, String> rowkeyAndValueMap = new TreeMap<>();
        hBaseDao.finds(table, start, end, rowkeyAndValueMap);
        if (rowkeyAndValueMap.size()<=0){
            return null;
        }
        int row = rowkeyAndValueMap.size();
        double[][] data = new double[row][col];
        int i = 0;
        for (String akey : rowkeyAndValueMap.keySet()) {
            // 时间处理 171020131415 转 2017-10-20 12:13:14
            String hbaseTime = akey.substring(4, 16).trim();
            time.add(getTimeS(hbaseTime));
            // 数据处理
            String value = rowkeyAndValueMap.get(akey);
            String[] valueArr = value.split(",",-1);
            for (int j = 0; j < col; j++) {
                if ("".equals(valueArr[j])){
                    valueArr[j] = "0";
                }
                data[i][j] = Double.valueOf(valueArr[j]);
            }
            i++;
        }
        return data;
    }

    // 获取Hbase数据库中指定天的 FBG应力 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static double[][] getHbaseAllFBGS(String date, List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 90;
        // title赋值
        String[] array = dataNameFBGS.split(",");
        title.addAll(Arrays.asList(array));
        // 取数据
        String sensorType = "ST";
        String table = "wuzhong";
        String start = "01" + sensorType + getHbaseDate(date) + "000000";
        String end   = "01" + sensorType + getHbaseDate(date) + "235959";
        Map<String, String> rowkeyAndValueMap = new TreeMap<>();
        hBaseDao.finds(table, start, end, rowkeyAndValueMap);
        if (rowkeyAndValueMap.size()<=0){
            return null;
        }
        int row = rowkeyAndValueMap.size();
        double[][] data = new double[row][col];
        int i = 0;
        for (String akey : rowkeyAndValueMap.keySet()) {
            // 时间处理 171020131415 转 2017-10-20 12:13:14
            String hbaseTime = akey.substring(4, 16).trim();
            time.add(getTimeS(hbaseTime));
            // 数据处理
            String value = rowkeyAndValueMap.get(akey);
            String[] valueArr = value.split(",");
            for (int j = 0; j < col; j++) {
                data[i][j] = Double.valueOf(valueArr[dataindexFBGS[j]]);
            }
            i++;
        }
        return data;
    }

    // 获取Hbase数据库中指定天的 FBG温度 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static double[][] getHbaseAllFBGT(String date, List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 231;
        // title赋值
        String[] array = dataNameFBGT.split(",");
        title.addAll(Arrays.asList(array));
        // 取数据
        String sensorType = "FT";
        String table = "wuzhong";
        String start = "01" + sensorType + getHbaseDate(date) + "000000";
        String end   = "01" + sensorType + getHbaseDate(date) + "235959";
        Map<String, String> rowkeyAndValueMap = new TreeMap<>();
        hBaseDao.finds(table, start, end, rowkeyAndValueMap);
        if (rowkeyAndValueMap.size()<=0){
            return null;
        }
        int row = rowkeyAndValueMap.size();
        double[][] data = new double[row][col];
        int i = 0;
        for (String akey : rowkeyAndValueMap.keySet()) {
            // 时间处理 171020131415 转 2017-10-20 12:13:14
            String hbaseTime = akey.substring(4, 16).trim();
            time.add(getTimeS(hbaseTime));
            // 数据处理
            String value = rowkeyAndValueMap.get(akey);
            String[] valueArr = value.split(",");
            for (int j = 0; j < col; j++) {
                data[i][j] = Double.valueOf(valueArr[dataindexFBGT[j]]);
            }
            i++;
        }
        return data;
    }

    // 获取Hbase数据库中指定天的 FBG 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static double[][] getHbaseAllFBG(String date, List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 321;
        // 取数据
        double[][] fbgs = getHbaseAllFBGS(date, title, time, hBaseDao);
        time.clear();
        double[][] fbgt = getHbaseAllFBGT(date, title, time, hBaseDao);
        if (fbgs == null || fbgt == null){
            return null;
        }
        int rowS = fbgs.length;
        int rowT = fbgt.length;
        int row = rowS < rowT?rowS:rowT;
        int colS = fbgs[0].length;
        int colT = fbgt[0].length;
        double[][] data = new double[fbgs.length][col];
        int k = 0;
        for (int j = 0; j < colS; j++) {
            for (int i = 0; i < row; i++) {
                data[i][k] = fbgs[i][j];
            }
            k++;
        }
        for (int j = 0; j < colT; j++) {
            for (int i = 0; i < row; i++) {
                data[i][k] = fbgt[i][j];
            }
            k++;
        }
        // title赋值
        String[] array = dataNameFBG.split(",");
        title.clear();
        title.addAll(Arrays.asList(array));
        return data;
    }

    // 获取Hbase数据库中指定天的 ENV 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static double[][] getHbaseAllENV(String date, List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 4;
        // title赋值
        String[] array = dataNameENV.split(",");
        title.addAll(Arrays.asList(array));
        // 取数据
        String sensorType = "ET";
        String table = "wuzhong";
        String start = "01" + sensorType + getHbaseDate(date) + "000000";
        String end   = "01" + sensorType + getHbaseDate(date) + "235959";
        Map<String, String> rowkeyAndValueMap = new TreeMap<>();
        hBaseDao.finds(table, start, end, rowkeyAndValueMap);
        if (rowkeyAndValueMap.size()<=0){
            return null;
        }
        int row = rowkeyAndValueMap.size();
        double[][] data = new double[row][col];
        int i = 0;
        for (String akey : rowkeyAndValueMap.keySet()) {
            // 时间处理 171020131415 转 2017-10-20 12:13:14
            String hbaseTime = akey.substring(4, 16).trim();
            time.add(getTimeS(hbaseTime));
            // 数据处理
            String value = rowkeyAndValueMap.get(akey);
            String[] valueArr = value.split(",");
            for (int j = 0; j < col; j++) {
                data[i][j] = Double.valueOf(valueArr[j]);
            }
            i++;
        }
        return data;
    }

    // 获取Hbase数据库中指定天的 CCD 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static double[][] getHbaseAllCCD(String date,  List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 3;
        // title赋值
        String[] array = dataNameCCD.split(",");
        title.addAll(Arrays.asList(array));
        // 取数据
        String sensorType = "CD";
        String table = "wuzhong";
        String start = "01" + sensorType + getHbaseDate(date) + "000000";
        String end   = "01" + sensorType + getHbaseDate(date) + "235959";
        Map<String, String> rowkeyAndValueMap = new TreeMap<>();
        hBaseDao.finds(table, start, end, rowkeyAndValueMap);
        if (rowkeyAndValueMap.size()<=0){
            return null;
        }
        int row = rowkeyAndValueMap.size();
        double[][] data = new double[row][col];
        int i = 0;
        for (String akey : rowkeyAndValueMap.keySet()) {
            // 时间处理 171020131415 转 2017-10-20 12:13:14
            String hbaseTime = akey.substring(4, 16).trim();
            time.add(getTimeS(hbaseTime));
            // 数据处理
            String value = rowkeyAndValueMap.get(akey);
            String[] valueArr = value.split(",");
            for (int j = 0; j < col; j++) {
                if (valueArr[j].contains("inf") || valueArr[j].contains("nan")){
                    valueArr[j] = "0";
                }
                data[i][j] = Double.valueOf(valueArr[j]);
            }
            i++;
        }
        return data;
    }

    // 获取Hbase数据库中指定天的 CNC 数据

    /**
     * @param date  日期 2017-11-27
     * @param title 数据抬头
     * @param time  时间序列 2017-11-27 12:13:14
     * @return 数据
     */
    public static String[][] getHbaseAllCNC(String date, List<String> title, List<String> time, IHBaseDao hBaseDao) {
        // 此类传感器个数
        int col = 16;
        // title赋值
        String[] array = dataNameCNC.split(",");
        title.addAll(Arrays.asList(array));
        // 取数据
        String sensorType = "CN";
        String table = "wuzhong";
        String start = "01" + sensorType + getHbaseDate(date) + "000000";
        String end   = "01" + sensorType + getHbaseDate(date) + "235959";
        Map<String, String> rowkeyAndValueMap = new TreeMap<>();
        hBaseDao.finds(table, start, end, rowkeyAndValueMap);
        if (rowkeyAndValueMap.size()<=0){
            return null;
        }
        int row = rowkeyAndValueMap.size();
        String[][] data = new String[row][col];
        int i = 0;
        for (String akey : rowkeyAndValueMap.keySet()) {
            // 时间处理 171020131415 转 2017-10-20 12:13:14
            String hbaseTime = akey.substring(4, 16).trim();
            time.add(getTimeS(hbaseTime));
            // 数据处理
            String value = rowkeyAndValueMap.get(akey);
            String[] valueArr = value.split(",");
            for (int j = 0; j < col; j++) {
                data[i][j] = valueArr[j];
            }
            i++;
        }
        return data;
    }


    // 诊断 电类温度 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisDSB(double[][] data, List<String> title, Map<String, String> diagnosisResult) {
        if (data == null){
            for (String aTitle : title) {
                diagnosisResult.put(aTitle, "无数据：当天未开启数据中心");
            }
            return;
        }
        int row = data.length;
        int col = data[0].length;

        // 0值统计、阈值判断 判断数据是否一直为0，出现0的次数
        for (int j = 0; j < col; j++) {
            int zeroCnt = 0;
            double max = -99999;
            double min = 99999;
            for (int i = 0; i < row; i++) {
                if (data[i][j] < 0.01 && data[i][j] > -0.01){
                    zeroCnt++;
                }
                max = max > data[i][j]? max:data[i][j];
                min = min < data[i][j]? min:data[i][j];
            }

            // 诊断
            if(max > 50 || min < -10){
                // 极值判断
                diagnosisResult.put(title.get(j), "故障：存在高于50或低于-10的值");
            }
            else if (zeroCnt == row){
                // 0值个数为全部
                diagnosisResult.put(title.get(j), "严重故障：恒为0值，传感器坏或线路故障");
            } else if (zeroCnt > row/5){
                // 0值个数大于全部的1/5
                diagnosisResult.put(title.get(j), "故障：大量0值，0值次数" + zeroCnt + "，传感器不稳定，需更换");
            } else if (zeroCnt < row/5 && zeroCnt > 20){
                // 0值个数小于全部的1/5
                diagnosisResult.put(title.get(j), "轻微故障：0值次数" + zeroCnt + "，可修复，但建议更换");
            } else if(zeroCnt <= 20){
                // 没有0值
                diagnosisResult.put(title.get(j), "正常");
            }
        }

        // 突变判断
        double[][] dataDelta = new double[row-1][col];
        for (int j = 0; j < col; j++) {
            for (int i = 1; i < row; i++) {
                dataDelta[i-1][j] = data[i][j] - data[i - 1][j];
            }
        }
        for (int j = 0; j < col; j++) {
            double max = -99999;
            double min = 99999;
            for (int i = 0; i < row-1; i++) {
                max = max > dataDelta[i][j]? max:dataDelta[i][j];
                min = min < dataDelta[i][j]? min:dataDelta[i][j];
            }
            // 诊断
            if ("正常".equals(diagnosisResult.get(title.get(j)))){
                if ( max > 3 || min < -3){
                    // 跳变 与前一个数值相差超过3
                    diagnosisResult.put(title.get(j), "故障：数据跳变");
                }
            }
        }

        // 恒值判断
        for (int j = 0; j < col; j++) {
            int constMaxCnt = -99999;
            int constCnt = 0;
            for (int i = 1; i < row; i++) {
                if(Math.abs(data[i][j] - data[i - 1][j]) < 0.00001){
                    constCnt++;
                }
                if(Math.abs(data[i][j] - data[i - 1][j]) > 0.00001){
                    constCnt = 0;
                }
                constMaxCnt = constMaxCnt > constCnt? constMaxCnt:constCnt;
            }
            // 诊断
            if ("正常".equals(diagnosisResult.get(title.get(j)))){
                if ( constMaxCnt > row/5){
                    // 恒值超过row/5次，说明有问题(24小时则4.8小时)
                    diagnosisResult.put(title.get(j), "疑似故障：数据长时间恒值，最长一次恒值"+constMaxCnt+"次，请检查传感器或供电系统");
                }
            }
        }
    }

    // 诊断 ENV 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisENV(double[][] data, List<String> title, Map<String, String> diagnosisResult) {
        diagnosisDSB(data, title, diagnosisResult);
    }

    // 诊断 FBG 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisFBG(double[][] data, List<String> title, Map<String, String> diagnosisResult) {
        if (data == null){
            title.clear();
            String[] array = dataNameFBG.split(",");
            title.addAll(Arrays.asList(array));
            for (String aTitle : title) {
                diagnosisResult.put(aTitle, "无数据：当天未开启数据中心");
            }
            return;
        }
        int row = data.length;
        int col = data[0].length;

        // 0值统计、阈值判断 判断数据是否一直为0，出现0的次数
        for (int j = 0; j < col; j++) {
            int zeroCnt = 0;
            double max = -99999;
            double min = 99999;
            for (int i = 0; i < row; i++) {
                if (data[i][j] < 0.01 && data[i][j] > -0.01){
                    zeroCnt++;
                }
                max = max > data[i][j]? max:data[i][j];
                min = min < data[i][j]? min:data[i][j];
            }

            // 诊断
//            if(max > 50 || min < -10){
//                // 极值判断
//                diagnosisResult.put(title.get(j), "故障：存在高于50或低于-10的值");
//            }
            if (zeroCnt == row){
                // 0值个数为全部
                diagnosisResult.put(title.get(j), "严重故障：恒为0值，传感器坏或线路故障");
            } else if (zeroCnt > row/5){
                // 0值个数大于全部的1/5
                diagnosisResult.put(title.get(j), "故障：大量0值，0值次数" + zeroCnt + "，传感器不稳定，需更换");
            } else if (zeroCnt < row/5 && zeroCnt > 20){
                // 0值个数小于全部的1/5
                diagnosisResult.put(title.get(j), "轻微故障：0值次数" + zeroCnt + "，可修复，但建议更换");
            } else if(zeroCnt <= 20){
                // 没有0值 (当下设定为小于20个)
                diagnosisResult.put(title.get(j), "正常");
            }
        }

        // 突变判断
//        double[][] dataDelta = new double[row-1][col];
//        for (int j = 0; j < col; j++) {
//            for (int i = 1; i < row; i++) {
//                dataDelta[i-1][j] = data[i][j] - data[i - 1][j];
//            }
//        }
//        for (int j = 0; j < col; j++) {
//            double max = -99999;
//            double min = 99999;
//            for (int i = 0; i < row-1; i++) {
//                max = max > dataDelta[i][j]? max:dataDelta[i][j];
//                min = min < dataDelta[i][j]? min:dataDelta[i][j];
//            }
            // 诊断
//            if ("正常".equals(diagnosisResult.get(title.get(j)))){
//                if ( max > 1.75 || min < -1.75){
//                    // 跳变 与前一个数值相差超过3
//                    System.out.println(max + " " + min);
//                    diagnosisResult.put(title.get(j), "故障：数据跳变");
//                }
//            }
//        }

        // 恒值判断
        for (int j = 0; j < col; j++) {
            int constMaxCnt = -99999;
            int constCnt = 0;
            for (int i = 1; i < row; i++) {
                if(Math.abs(data[i][j] - data[i - 1][j]) < 0.00001){
                    constCnt++;
                }
                if(Math.abs(data[i][j] - data[i - 1][j]) > 0.00001){
                    constCnt = 0;
                }
                constMaxCnt = constMaxCnt > constCnt? constMaxCnt:constCnt;
            }
            // 诊断
            if ("正常".equals(diagnosisResult.get(title.get(j)))){
                if ( constMaxCnt > row/5){
                    // 恒值超过row/5次，说明有问题(24小时则4.8小时)   恒值超过700次，说明有问题
                    diagnosisResult.put(title.get(j), "疑似故障：数据长时间恒值，最长一次恒值"+constMaxCnt+"次，请检查传感器或供电系统");
                }
            }
        }
    }

    // 诊断 CCD 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisCCD(double[][] data, List<String> title, Map<String, String> diagnosisResult) {
        if (data == null){
            title.clear();
            String[] array = dataNameCCD.split(",");
            title.addAll(Arrays.asList(array));
            for (String aTitle : title) {
                diagnosisResult.put(aTitle, "无数据：当天未开启数据中心");
            }
            return;
        }
        int row = data.length;
        int col = data[0].length;

        // 0值统计
        for (int j = 0; j < col; j++) {
            int zeroCnt = 0;
            double max = -99999;
            double min = 99999;
            for (int i = 0; i < row; i++) {
                if (data[i][j] < 0.00001 && data[i][j] > -0.00001){
                    zeroCnt++;
                }
                max = max > data[i][j]? max:data[i][j];
                min = min < data[i][j]? min:data[i][j];
            }
            // 诊断 只有全0和不全0两种诊断
            if (zeroCnt == row){
                // 0值个数为全部
                diagnosisResult.put(title.get(j), "严重故障：恒为0值，传感器坏或线路故障");
            }  else {
                // 没有0值
                diagnosisResult.put(title.get(j), "正常");
            }
        }
    }

    // 诊断 CNC 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisCNC(String[][] data, List<String> title, Map<String, String> diagnosisResult) {

    }

    // 诊断 SST 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisFBGS(double[][] data, List<String> title, Map<String, String> diagnosisResult) {
        diagnosisFBG(data, title, diagnosisResult);
    }

    // 诊断 SFT 数据

    /**
     * @param data            输入数据
     * @param title           数据抬头
     * @param diagnosisResult 诊断结果 传感器编号：正常
     */
    public static void diagnosisFBGT(double[][] data, List<String> title, Map<String, String> diagnosisResult) {
        diagnosisFBG(data, title, diagnosisResult);
    }

    // 传感器诊断 总的统计信息
    public static void diagnosisSensorSumMsg(Map<String, String> inputMap, Map<String, String> outputMap){
        int envSum = 0;
        int envOKCnt = 0;
        int dsbSum = 0;
        int dsbOKCnt = 0;
        int fbgSum = 0;
        int fbgOKCnt = 0;
        int ccdSum = 0;
        int ccdOKCnt = 0;
//        System.out.println("diagnosisSensorMapSize:" + map.size());
        // 正常比例统计
        Map<String, String> diagnosisChannelMap = new TreeMap<>();
        for (String aKay : inputMap.keySet()) {
            // 整体正常比例统计
            if (aKay.contains("SET")) {
                envSum++;
                if (inputMap.get(aKay).contains("正常")) {
                    envOKCnt++;
                }
            } else if (aKay.contains("SDT")) {
                dsbSum++;
                if (inputMap.get(aKay).contains("正常")) {
                    dsbOKCnt++;
                }
            } else if (aKay.contains("SFT")) {
                fbgSum++;
                if (inputMap.get(aKay).contains("正常")) {
                    fbgOKCnt++;
                }
            } else if (aKay.contains("SCD")) {
                ccdSum++;
                if (inputMap.get(aKay).contains("正常")) {
                    ccdOKCnt++;
                }
            }

            // 单通道正常比例统计
            // key:001-SDT00  value: 正常个数、总数
//            System.out.println(aKay + "  " + inputMap.get(aKay));
            int[] value = new int[2];
            String valueOld = diagnosisChannelMap.get(aKay.substring(0, 9));
            if (valueOld == null) {
                valueOld = "0,0";
            }
            String[] arr = valueOld.split(",");
            value[1] = Integer.valueOf(arr[1]) + 1;
            if (inputMap.get(aKay).contains("正常")) {
                value[0] = Integer.valueOf(arr[0]) + 1;
            } else {
                // 故障则不加1
                value[0] = Integer.valueOf(arr[0]);
            }
            String valueStr = value[0] + "," + value[1];
            diagnosisChannelMap.put(aKay.substring(0, 9), valueStr);
        }
//        show(diagnosisChannelMap);
        int envOKPercent = envOKCnt * 100 / envSum;
        int dsbOKPercent = dsbOKCnt * 100 / dsbSum;
        int fbgOKPercent = fbgOKCnt * 100 / fbgSum;
        int ccdOKPercent = ccdOKCnt * 100 / ccdSum;

        outputMap.putAll(diagnosisChannelMap);
        outputMap.put("allEnvOKPercent", String.valueOf(envOKPercent));
        outputMap.put("allDsbOKPercent", String.valueOf(dsbOKPercent));
        outputMap.put("allFbgOKPercent", String.valueOf(fbgOKPercent));
        outputMap.put("allCcdOKPercent", String.valueOf(ccdOKPercent));
    }

    public static String diagnosisSensorToCache(String date, Map<String, String> map){
        if (date==null || map==null){
            return "";
        }
        List<DiagnoseSensorVo> list = new ArrayList<>();
        for (String aKay : map.keySet()) {
            DiagnoseSensorVo diagnoseSensorVo = new DiagnoseSensorVo();
            if (aKay.contains("SET")) {
                diagnoseSensorVo.setType("【环境温度】");
            } else if (aKay.contains("SDT")) {
                diagnoseSensorVo.setType("电类温度");
            } else if (aKay.contains("SFT")) {
                diagnoseSensorVo.setType("FBG传感器");
            } else if (aKay.contains("SCD")) {
                diagnoseSensorVo.setType("CCD位移");
            }
            diagnoseSensorVo.setId(aKay);
            diagnoseSensorVo.setResult(map.get(aKay));
            list.add(diagnoseSensorVo);
        }
        return JSON.toJSONString(list);
    }

    public static void main(String[] args){
//        double[][] data = {{0,2,3},{0,2,3},{0,2,3}};
//        List<String> title = new ArrayList<>();
//        title.add("数据1");
//        title.add("数据2");
//        title.add("数据3");
//        Map<String, String> diagnosisResult = new TreeMap<>();
//        diagnosisDSB(data, title, diagnosisResult);
//        show(diagnosisResult);
    }
}
